# -*- conding:UTF-8 -*-

'''
@ Project: P8 flask_progect
@ File: pay.py
@ Author: 罗婷
@ Date：2022/6/28 16:48

'''

# 获取订单号  创建订单 /pay/create_order

import json
import random
import time
from alipay import AliPay
from flask import Blueprint, jsonify
from flask_restful import Api, Resource, reqparse
from common.jwt.check_token import token_check
from common.models.orders import OrderModel
from common.models.users import *


pay_bp = Blueprint('pay_bp', __name__,url_prefix='/pay')

api = Api(pay_bp)

# 生成订单号  创建订单
class CreateOrder(Resource):
    def get(self):
        parser = reqparse.RequestParser()
        parser.add_argument('grade')
        parser.add_argument('price')
        parser.add_argument('token')
        args = parser.parse_args()
        grade = args['grade']
        price = args['price']
        token = args['token']
        # print('创建订单^^^^^^^^', 'grade', grade, 'price', price, 'token', token)
        # 校验token
        payload = token_check(token)
        # print('校验出的payloa@@@@@@@', payload)
        # {'uid': 1, 'account': 'admin1', 'exp': 1656336094}
        uid = payload['uid']
        # TODO 时间戳要转数字再计算
        order_id = str(int(time.time())*1000000) + str(uid) + str(random.randint(10000, 99999))
        return jsonify(message='创建订单', code=200, data=order_id)

# 阿里pay 的基本信息封装   阿里公钥 和 私钥   创建阿里的对象
class AlipayObject():
    def __init__(self):
        # 1 获取 阿里公钥 和 私钥
        self.app_private_key_string = open('common/pay_key/app_private_key.pem').read()       # 私钥
        self.alipay_public_key_string = open('common/pay_key/alipay_public_key.pem').read()   # 阿里公钥

        # 2 创建阿里的对象
        self.alipay = AliPay(
            appid="2021000119664049",    # 沙箱appID
            app_notify_url='http://127.0.0.1:8080/callback',  # 默认回调url
            app_private_key_string=self.app_private_key_string,     # 私钥
            alipay_public_key_string=self.alipay_public_key_string,  # 阿里公钥
            debug=True)

class AliPayResource(Resource):

    # 创建一个阿里对象  网关地址
    def __init__(self):
        # 调用封装的阿里类生成一个对象
        self.alipay = AlipayObject().alipay
        # 支付宝网关地址    获取支付宝登录的url使用
        self.alipay_getway = 'https://openapi.alipaydev.com/gateway.do'

    # 创建订单
    def post(self):
        """创建订单
        获取参数 给订单表添加一条数据
        """
        parser = reqparse.RequestParser()
        parser.add_argument('order')
        parser.add_argument('price')
        parser.add_argument('token')
        parser.add_argument('record')
        args = parser.parse_args()
        order_id = args.get('order')
        price = args.get('price')
        grade = args.get('record')
        token = args.get('token')
        print('获取到的参数^^^^^^^^',
              'order_id', order_id, 'price', price, 'grade', grade, 'token', token)
        try:
            payload = token_check(token)
        except Exception as e:
            return jsonify(message='请先登录',code=401)
        # 获取用户id    # {'uid': 1, 'account': 'admin1', 'exp': 1656336094}
        uid = payload['uid']
        if grade == '免费':
            grade = 0
        if grade == '普通会员':
            grade = 1
        if grade == '高级会员':
            grade = 2
        vip = VipModel.query.filter_by(level=grade).first()
        try:
            order = OrderModel(
                order_id=order_id,
                user_id=uid,
                vip=vip.id,
                trade_no=order_id,
                pay_amount=price
            )
            db.session.add(order)
            db.session.commit()
            return jsonify(message="创建订单成功", code=200)
        except Exception:
            return jsonify(message="创建订单失败", code=500)

    # 获取支付宝登录的url
    def get(self):
        parser = reqparse.RequestParser()
        parser.add_argument('order')
        parser.add_argument('price')
        args = parser.parse_args()
        order_id = args.get('order')
        price = args.get('price')

        # 统一下单并支付 页面接口 要传入参数1234
        data = self.aliay.api_alipay_trade_page_pay(
            subject="实验楼购买会员消费",    # 商品名称
            out_trade_no="%s" % order_id,    # 订单编号
            total_amount=price,              # 交易金额
            return_url='http://127.0.0.1:8080/callback'  # 回调地址 前端回调页面
        )
        # 支付宝登录的url : 支付宝网关地址  + '?' +  下单并支付的页面接口数据
        url = self.alipay_getway + '?' + data
        print('url>>>', url)
        return jsonify(message="请求成功，跳转支付页面", data=url, code=200)


class CheckAlipay(Resource):
    def get(self):
        """验证支付是否成功"""
        parser = reqparse.RequestParser()
        parser.add_argument('token')
        parser.add_argument('data')
        args = parser.parse_args()
        token = args.get('token')  #
        data_ = args.get('data')  # 回调的查询字符串  回调显示的地址 携带参数
        print('token, data_', token, '\n', data_)
        try:
            payload = token_check(token)
        except Exception as e:
            print(e)
            return jsonify(message='请先登录', code=401)
        # 校验是否是 真正支付成功
        data = json.loads(data_)
        signature = data.pop("sign")   # pop 删除data里的sign  signature里没有sing  sing不参与签名验证
        # print('data>>', data)
        # print('sign>>>',signature)
        alipay = AlipayObject().alipay  # 生成一个阿里对象
        # 验证是否支付成功  返回布尔值
        result = alipay.verify(data, signature)
        # print("支付的结果>>",result)
        if result:
            return jsonify(message="支付成功", code=200)
        else:
            return jsonify(message="支付失败", code=500)


class ChangeOrderStatus(Resource):
    def get(self):
        """修改订单状态"""
        parser = reqparse.RequestParser()
        parser.add_argument('token')
        parser.add_argument('order')
        args = parser.parse_args()
        token = args.get('token')
        order_id = args.get('order')  # 回调的查询字符串
        try:
            payload = token_check(token)
        except Exception as e:
            print(e)
            return jsonify(message='请先登录', code=401)
        try:
            OrderModel.query.filter_by(order_id=order_id,user_id= payload['uid']).update({'status':1})
            db.session.commit()
            return jsonify(message="支付成功", code=200)
        except Exception as e:
            return jsonify(message="修改订单状态失败", code=500)


# 获取订单号  创建订单
api.add_resource(CreateOrder, '/create_order')
api.add_resource(AliPayResource, '/alipay')















